package com.yq.ylmall.wechat.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;

/**
 * @Project: yourlife
 * @Name: WechatPayConfig
 * @Author: Jack_Li
 * @Date: 2024/6/13 20:27
 */

@Slf4j
@Configuration
@PropertySource("classpath:application-dev.yml")
@ConfigurationProperties(prefix = "wechat")
@Data
public class WechatPayConfig {

    // 商户号
    private String mchId;

    // 商户 API 证书序列号
    private String mchSerialNo;

    // 商户私钥文件
    private String privateKeyPath;

    // API v3 密钥
    private String apiV3Key;

    // APPID
    private String appid;

    // 微信服务器地址
    private String domain;

    // 微信回调地址
    private String notifyDomain;

    private PrivateKey getPrivateKey(String filename) {
        try {
            return PemUtil.loadPrivateKey(WechatPayConfig.class.getResourceAsStream("/" + filename));
        } catch (Exception e) {
            throw new RuntimeException("私钥文件流不存在", e);
        }
    }

    /**
     * 获取签名认证器
     * @return
     */
    @Bean
    public ScheduledUpdateCertificatesVerifier getVerifier() {

        // 获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);

        // 私钥签名对象
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);

        // 身份认证对象
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);

        // 使用定时跟新的签名验证器，不需要传入证书
        ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
                wechatPay2Credentials,
                apiV3Key.getBytes(StandardCharsets.UTF_8));
        return verifier;
    }

    /**
     * 获取 http 请求对象
     * @param verifier
     * @return
     */
    @Bean
    public CloseableHttpClient getWechatPayClient(ScheduledUpdateCertificatesVerifier verifier) {
        // 获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, privateKey)
                .withValidator(new WechatPay2Validator(verifier));
        // 通过 WechatHttpClientBuilder 构造的 HttpClient 会自动的处理签名和验签 并进行证书自动更新
        CloseableHttpClient httpClient = builder.build();

        return httpClient;
    }

}
